package com.shrct.businessprocess.project.impl;

import com.google.common.base.Objects;
import com.google.common.collect.Iterables;
import com.shrct.businessprocess.budget.BudgetType;
import com.shrct.businessprocess.budget.BudgetTypeManager;
import com.shrct.businessprocess.budget.RCBudget;
import com.shrct.businessprocess.budget.RCC3Budget;
import com.shrct.businessprocess.budget.RCC3BudgetType;
import com.shrct.businessprocess.budget.RCCostBreakDown;
import com.shrct.businessprocess.budget.impl.RCCostBreakDownImpl;
import com.shrct.businessprocess.common.CurrencyType;
import com.shrct.businessprocess.common.RCTaskProxy;
import com.shrct.businessprocess.customerservice.RCProjectReference;
import com.shrct.businessprocess.organization.RCEmployee;
import com.shrct.businessprocess.project.RCInitializeProjectProcess;
import com.shrct.businessprocess.project.RCProject;
import com.shrct.businessprocess.project.RCProjectCreditStat;
import com.shrct.businessprocess.project.RCProjectDAO;
import com.shrct.businessprocess.project.RCProjectStat;
import com.shrct.businessprocess.project.RCProjectStatus;
import com.shrct.businessprocess.project.RCProjectTypeExtensionDAO;
import com.shrct.businessprocess.project.events.RCProjectEventsManager;
import com.shrct.businessprocess.project.impl.RCInitializeProjectProcessImpl;
import com.shrct.businessprocess.project.impl.RCProjectImpl;
import com.shrct.businessprocess.project.impl.RCProjectStatImpl;
import com.uniquesoft.uidl.validation.Validates;
import edu.fudan.langlab.domain.security.ISystemUserService;
import edu.fudan.langlab.domain.workflow.ProcessTask;
import edu.fudan.langlab.domain.workflow.Token;
import edu.fudan.mylang.pf.BaseService;
import edu.fudan.mylang.pf.IGenericQuery;
import edu.fudan.mylang.pf.IObjectFactory;
import java.util.Collection;
import java.util.List;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service("com.shrct.businessprocess.project.RCProjectDAO")
public class RCProjectDAOImpl extends BaseService implements RCProjectDAO {
  @Autowired
  private ISystemUserService systemUserService;
  
  @Autowired
  private BudgetTypeManager budgetTypeManager;
  
  @Autowired
  private RCProjectEventsManager eventsManager;
  
  @Autowired
  private IObjectFactory entities;
  
  @Autowired
  private RCProjectTypeExtensionDAO projectTypeExtensionDAO;
  
  public RCProject createProject(final Procedure1<? super RCProject> preInit) {
    RCProject _xblockexpression = null;
    {RCProject rCProject=RCProjectImpl.create(getObjectFactory());
      final Procedure1<RCProject> _function = new Procedure1<RCProject>() {
          public void apply(final RCProject project) {RCCostBreakDown rCCostBreakDown=RCCostBreakDownImpl.create(getObjectFactory());
            final Procedure1<RCCostBreakDown> _function = new Procedure1<RCCostBreakDown>() {
                public void apply(final RCCostBreakDown cbd) {
                  cbd.setProject(project);
                }
              };
            RCCostBreakDown _doubleArrow = ObjectExtensions.<RCCostBreakDown>operator_doubleArrow(rCCostBreakDown, _function);
            project.setCbd(_doubleArrow);
          }
        };
      final RCProject project = ObjectExtensions.<RCProject>operator_doubleArrow(rCProject, _function);
      preInit.apply(project);
      RCEmployee _businessMan = project.getBusinessMan();
      boolean _notEquals = (!Objects.equal(_businessMan, null));
      Validates.Assert(_notEquals, "\u65E0\u6CD5\u83B7\u53D6\u9ED8\u8BA4\u5546\u52A1");
      project.setStatus(RCProjectStatus.creating);RCProjectStat rCProjectStat=RCProjectStatImpl.create(getObjectFactory());
      project.setStat(rCProjectStat);
      List<BudgetType> _allBudgetTypes = this.budgetTypeManager.getAllBudgetTypes();
      final Function1<BudgetType,Boolean> _function_1 = new Function1<BudgetType,Boolean>() {
          public Boolean apply(final BudgetType it) {
            Function1<? super RCProject,? extends RCBudget> _creator = it.getCreator();
            boolean _notEquals = (!Objects.equal(_creator, null));
            return Boolean.valueOf(_notEquals);
          }
        };
      Iterable<BudgetType> _filter = IterableExtensions.<BudgetType>filter(_allBudgetTypes, _function_1);
      final Procedure1<BudgetType> _function_2 = new Procedure1<BudgetType>() {
          public void apply(final BudgetType it) {
            Function1<? super RCProject,? extends RCBudget> _creator = it.getCreator();
            final RCBudget budget = _creator.apply(project);
            RCCostBreakDown _cbd = project.getCbd();
            budget.setCbd(_cbd);
          }
        };
      IterableExtensions.<BudgetType>forEach(_filter, _function_2);
      this.projectTypeExtensionDAO.asDeliver(project);
      this.eventsManager.fireCreated(project);
      project.start();
      _xblockexpression = (project);
    }
    return _xblockexpression;
  }
  
  public void deleteProject(final RCProject project) {
    RCCostBreakDown _cbd = project.getCbd();getObjectFactory().delete(_cbd);
    getObjectFactory().delete(project);
    
    this.eventsManager.fireDeleted(project);
  }
  
  public void deletePassedProject(final RCProject p) {
    IGenericQuery<RCInitializeProjectProcess> query=getObjectFactory().createGenericQuery(RCInitializeProjectProcess.class,"select e from com.shrct.businessprocess.project.impl.RCInitializeProjectProcessImpl as e   where ((e.project) = (:p)) and  e.active = 1      ").setParameter("p",p);
    final RCInitializeProjectProcess bp = query.uniqueResult();
    IGenericQuery<Token> query_1=getObjectFactory().createGenericQuery(Token.class,"select e from edu.fudan.langlab.domain.workflow.impl.TokenImpl as e   where ((e.bp) = (:bp)) and  e.active = 1      ").setParameter("bp",bp);
    Collection<Token> _list = query_1.list();
    final Procedure1<Token> _function = new Procedure1<Token>() {
        public void apply(final Token it) {
          IGenericQuery<ProcessTask> query=getObjectFactory().createGenericQuery(ProcessTask.class,"select pt from edu.fudan.langlab.domain.workflow.impl.ProcessTaskImpl as pt   where ((pt.token) = (:it)) and  pt.active = 1      ").setParameter("it",it);
          final ProcessTask task = query.uniqueResult();
          IGenericQuery<RCTaskProxy> query_1=getObjectFactory().createGenericQuery(RCTaskProxy.class,"select rtp from com.shrct.businessprocess.common.impl.RCTaskProxyImpl as rtp   where ((rtp.task) = (:task)) and  rtp.active = 1      ").setParameter("task",task);
          final RCTaskProxy rctask = query_1.uniqueResult();getObjectFactory().delete(rctask);
          getObjectFactory().delete(task);
          getObjectFactory().delete(it);
          
        }
      };
    IterableExtensions.<Token>forEach(_list, _function);
    this.entities.delete(bp);
    IGenericQuery<RCProjectCreditStat> query_2=getObjectFactory().createGenericQuery(RCProjectCreditStat.class,"select e1 from com.shrct.businessprocess.project.impl.RCProjectCreditStatImpl as e1   where ((e1.project) = (:p)) and  e1.active = 1      ").setParameter("p",p);
    RCProjectCreditStat _uniqueResult = query_2.uniqueResult();getObjectFactory().delete(_uniqueResult);
    
    IGenericQuery<RCProjectReference> query_3=getObjectFactory().createGenericQuery(RCProjectReference.class,"select pr from com.shrct.businessprocess.customerservice.impl.RCProjectReferenceImpl as pr   where ((pr.customerContract.project) = (:p)) and  pr.active = 1      ").setParameter("p",p);
    Collection<RCProjectReference> _list_1 = query_3.list();
    final Procedure1<RCProjectReference> _function_1 = new Procedure1<RCProjectReference>() {
        public void apply(final RCProjectReference it) {getObjectFactory().delete(it);
          
        }
      };
    IterableExtensions.<RCProjectReference>forEach(_list_1, _function_1);getObjectFactory().delete(p);
    
  }
  
  public RCInitializeProjectProcess createInitializeProjectProcess(final RCProject project) {
    RCInitializeProjectProcess _xblockexpression = null;
    {
      RCCostBreakDown _cbd = project.getCbd();
      Collection<RCBudget> _budgets = _cbd.getBudgets();
      Iterable<RCC3Budget> _filter = Iterables.<RCC3Budget>filter(_budgets, RCC3Budget.class);
      RCC3Budget _head = IterableExtensions.<RCC3Budget>head(_filter);
      RCC3BudgetType _type = _head.getType();
      boolean _notEquals = (!Objects.equal(_type, RCC3BudgetType.P0));
      Validates.Assert(_notEquals, "\u5FC5\u987B\u9009\u62E9\u5DE5\u7A0B\u5E08\u670D\u52A1\u7C7B\u578B");
      RCInitializeProjectProcess _initializeProcess = project.getInitializeProcess();
      boolean _equals = Objects.equal(_initializeProcess, null);
      Validates.Assert(_equals, "\u5DF2\u542F\u52A8\u5BA1\u6279\u6D41\u7A0B");
      IObjectFactory _objectFactory = this.getObjectFactory();
      RCInitializeProjectProcess _create = RCInitializeProjectProcessImpl.create(_objectFactory);
      final Procedure1<RCInitializeProjectProcess> _function = new Procedure1<RCInitializeProjectProcess>() {
          public void apply(final RCInitializeProjectProcess it) {
            it.start(project);
          }
        };
      RCInitializeProjectProcess _doubleArrow = ObjectExtensions.<RCInitializeProjectProcess>operator_doubleArrow(_create, _function);
      _xblockexpression = (_doubleArrow);
    }
    return _xblockexpression;
  }
  
  public CurrencyType getDefaultCurrencyCode() {
    CurrencyType _xblockexpression = null;
    {
      IGenericQuery<CurrencyType> query=getObjectFactory().createGenericQuery(CurrencyType.class,"select ct from com.shrct.businessprocess.common.impl.CurrencyTypeImpl as ct   where ((ct.codeid) = ( '01' )) and  ct.active = 1      ");
      CurrencyType result = query.uniqueResult();
      boolean _equals = Objects.equal(result, null);
      if (_equals) {
        RuntimeException _runtimeException = new RuntimeException("Default Currency not Initialized");
        throw _runtimeException;
      }
      _xblockexpression = (result);
    }
    return _xblockexpression;
  }
  
  public CurrencyType getUSDollarCurrencyCode() {
    CurrencyType _xblockexpression = null;
    {
      IGenericQuery<CurrencyType> query=getObjectFactory().createGenericQuery(CurrencyType.class,"select ct from com.shrct.businessprocess.common.impl.CurrencyTypeImpl as ct   where ((ct.codeid) = ( '02' )) and  ct.active = 1      ");
      CurrencyType result = query.uniqueResult();
      boolean _equals = Objects.equal(result, null);
      if (_equals) {
        RuntimeException _runtimeException = new RuntimeException("Default Currency not Initialized");
        throw _runtimeException;
      }
      _xblockexpression = (result);
    }
    return _xblockexpression;
  }
  
  public void fixActualCost() {
    IGenericQuery<RCProject> query=getObjectFactory().createGenericQuery(RCProject.class,"select e from com.shrct.businessprocess.project.impl.RCProjectImpl as e   where ((e.passed) = (true)) and  e.active = 1      ");
    Collection<RCProject> _list = query.list();
    final Procedure1<RCProject> _function = new Procedure1<RCProject>() {
        public void apply(final RCProject it) {
          it.fixActuralCostReport();
        }
      };
    IterableExtensions.<RCProject>forEach(_list, _function);
  }
}
